Skip to content

fix(Filter::Util::Call): implement method filters and fix block-mode filter_read#521

Merged
fglock merged 1 commit intomasterfrom
fix/filter-util-call-method-filters
Apr 21, 2026
Merged

fix(Filter::Util::Call): implement method filters and fix block-mode filter_read#521
fglock merged 1 commit intomasterfrom
fix/filter-util-call-method-filters

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 21, 2026

Summary

Makes CPAN's Switch module (and any other module that uses method-style source filters via Filter::Util::Call) work on PerlOnJava.

./jcpan -t Switch before: all 3 test files fail with syntax error ... near "" (0/3).
./jcpan -t Switch after: Files=3, Tests=590, Result: PASS.

Root cause

Switch.pm is a source filter. In its import() it calls filter_add({}) (a hashref), which Filter::Util::Call blesses into the caller's package — a method filter. Its filter() method does filter_read(1_000_000) to slurp the whole source, then rewrites switch/case blocks via Text::Balanced.

Two bugs in FilterUtilCall.java broke this:

  1. Method filters were unimplemented. applyFilters() had an explicit // TODO: Implement method filter calling branch that just returned the source unchanged, so switch (...) { case ... } was passed verbatim to the parser.
  2. filter_read($blocksize) was broken in block mode. The read loop broke out on the first "\n", turning block reads into line reads. Switch::filter asked for 1,000,000 bytes but got only "\n" then "switch (1) {\n", so Text::Balanced::_match_codeblock failed with Bad switch statement (problem in the code block?).

Fix

In src/main/java/org/perlonjava/runtime/perlmodule/FilterUtilCall.java:

  • Method-filter support: resolve ${pkg}::filter via InheritanceResolver.findMethodInHierarchy, call it with the blessed filter object as $self, accumulate $_, and loop until status ≤ 0 — matching the closure-filter loop that was already there.
  • Block-mode fix: remove the erroneous if (line.endsWith("\n")) break; so filter_read($n) reads up to $n bytes instead of up to one line.

Test plan

  • make — BUILD SUCCESSFUL, all unit tests pass, no regressions
  • ./jcpan -t SwitchFiles=3, Tests=590, Result: PASS
    • t/given.t — 293/293
    • t/nested.t — 4/4
    • t/switch.t — 293/293

Generated with Devin

…filter_read

Two bugs in FilterUtilCall prevented source-filter modules that use the
method-filter form (e.g. CPAN's Switch.pm) from working:

1. Method filters were unimplemented. applyFilters() had a TODO branch
   that returned the source unchanged whenever filter_add was called
   with a blessed ref instead of a coderef, so `use Switch` never
   rewrote any switch/case blocks and produced a bare syntax error.
   Now we look up ${pkg}::filter via InheritanceResolver and drive it
   the same way we drive closure filters: call it with $self as the
   first arg, accumulate $_, loop until status <= 0.

2. filter_read($blocksize) wrongly terminated block reads at the first
   "\n", turning block mode into line mode. Switch::filter asks for
   1_000_000 bytes expecting the whole source, but only got one line
   per call, which made Text::Balanced::_match_codeblock fail with
   "Bad switch statement (problem in the code block?)". Removed the
   early newline break so block mode reads up to $blocksize bytes.

Verified with `./jcpan -t Switch`: Files=3, Tests=590, Result: PASS
(was 0/3 test files before, all failing with syntax errors). `make`
still passes with no unit-test regressions.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock force-pushed the fix/filter-util-call-method-filters branch from 8c003b7 to 8769858 Compare April 21, 2026 09:57
@fglock fglock merged commit 250de1e into master Apr 21, 2026
2 checks passed
@fglock fglock deleted the fix/filter-util-call-method-filters branch April 21, 2026 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant